/**
 * 
 */
package sg.edu.nus.iss.vmcs.payment;

import java.util.Observable;

import sg.edu.nus.iss.vmcs.customer.TransactionController;
import sg.edu.nus.iss.vmcs.store.CashStoreItem;
import sg.edu.nus.iss.vmcs.store.Coin;
import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.system.Fault;
import sg.edu.nus.iss.vmcs.system.FaultType;
import sg.edu.nus.iss.vmcs.util.Log;
import sg.edu.nus.iss.vmcs.util.VMCSException;

public class ChangeGiver {
	
	private CoinPayment 	ctrl = null;
	private Store 					cashStore = null;
	
	public ChangeGiver(CoinPayment ctrl) {
		this.ctrl = ctrl;
		cashStore = ctrl.getStoreController().getStore(Store.CASH);
	}
	
	public void resetChange() {
		ctrl.getPanel().setValueRefundChangeTrayDisplay("0");
	}	

	public boolean giveChange(int change_required) throws VMCSException {
		int i, len, changeRequired, changeGiven;
		boolean success = true;
		
		changeRequired = change_required;
		changeGiven = 0; 
		len = cashStore.getStoreSize();
		
		for (i = len - 1; i >= 0; i--) {
			int coinQty = ((CashStoreItem) cashStore.getStoreItem(i)).getQuantity();
			Coin coin = (Coin) ((CashStoreItem) cashStore.getStoreItem(i)).getContent();
			int coinValue = coin.getValue();
			int changeQty = 0;
			while ((changeRequired >= coinValue) && (changeQty <= coinQty)) {
				changeQty = changeQty + 1;
				changeRequired = changeRequired - coinValue;
			}
			
			if (coinQty > 0) {
				if (changeQty <= coinQty) {
					try {						
						ctrl.getMainController().getMachineryController().giveChange(i, changeQty);
					} catch (VMCSException e) {
						throw new VMCSException(
							"ChangeGiver.giveChange",
							e.getMessage());
					}
					changeGiven = changeGiven + (coinValue * changeQty);
				}
			}
		}
		ctrl.getPanel().setValueRefundChangeTrayDisplay(String.valueOf(changeGiven));
		if(changeRequired > 0 ) {
			ctrl.getPanel().setStateNoChangeAvailableDisplay(true);
		}
		
		return success;
	}
	
	public void displayChangeStatus() { 
		int i, len, change;
		boolean changeAvailable = true;
		
		len = cashStore.getStoreSize();
		CashStoreItem[] items = new CashStoreItem[len]; 
		
		for (i = 0; i < len; i++) {
			items[i] = (CashStoreItem) cashStore.getStoreItem(i);
		}
		
		change = ((Coin) items[len-1].getContent()).getValue();
		
		for (i = len - 2; i >= 0; i--) {
			int value = ((Coin) items[i].getContent()).getValue();
			int minQty;
			if (change % value == 0) {
				minQty = (change / value) - 1;
			}
			else {
				minQty = change / value;
			}
			if (minQty < 1) {
				minQty = 1;
			}
			if (items[i].getQuantity() < minQty) {
				changeAvailable = false;
			}
			change = change - ( minQty * value );			
		}
		
		ctrl.getPanel().setStateNoChangeAvailableDisplay(!changeAvailable);
	}

	public boolean StoreCash(){
		
		boolean success = true;
		
//		tCtrl.mCtrl.getStoreController().getStore(Store.CASH).setQuantity()
//		update total and reset totalmoneyinserteddisplaytozero
		return success;
	}

	/**
	 * Set Error status of Change Giver
	 * 
	 * @param err
	 *     True - ChangeGiver Has Error 
	 *     False - ChangeGiver Error was cleared
	 */
	public void setError(boolean err) {
		Log.LogIt("ChangeGiver.setErr:" + err);
		Fault fault = getFault();
		if (err) {
			fault.setState(FaultType.ChangeGiverFault);
		} else {
			if (fault.getState().compareTo(FaultType.ChangeGiverFault) == 0) {
				// Current Fault is Change Giver Fault. Reset it.
				fault.setState(FaultType.NO_FAULT);
			}
		}
	}

	private Fault getFault() {
		return  Fault.getInstance();
	}
	
	
}
